﻿//----------------------------------------------------------------
// Copyright (c) 2011-2013 
// All rights reserved.
// Author: Ben DaoWei 
// Contact: bendaowei@gmail.com
// Web Link: http://xnaeditor.codeplex.com
// ----------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MdxLib.Model;
using Microsoft.Xna.Framework;
using System.Diagnostics;

namespace UnityEngine.Graphics
{
    public class SequenceAnimationPlayer
    {
        private List<CSequence> _Sequences;

        public CSequence[] Sequences
        {
            get
            {
                return _Sequences.ToArray();
            }
        }

        private int _CurrnetClipIndex;
        private SequencePlayer _SequencePlayer;

        public SequencePlayer SequencePlayer
        {
            get
            {
                return _SequencePlayer;
            }
        }

        public int CurrentTick
        {
            get 
            { 
                return _SequencePlayer.CurrentTick; 
            }
        }

        public bool IsPlaying
        {
            get { return _SequencePlayer.IsPlaying; }
        }

        public SequenceAnimationPlayer(CObjectContainer<CSequence> sequences)
            : this(sequences.ToList<CSequence>())
        {
            this.SetAnimationClip(0);
        }

        public SequenceAnimationPlayer(List<CSequence> sequences)
        {
            _Sequences = sequences;
        }

        public void SetAnimationClip(int clipIndex)
        {
            _CurrnetClipIndex = clipIndex;
            _SequencePlayer = new SequencePlayer(_Sequences[clipIndex]);
        }

        private void Reset()
        {
            if (_SequencePlayer != null)
                _SequencePlayer.Reset();
        }

        public void Update(TimeSpan elapsedTime)
        {
            if (_SequencePlayer != null)
                _SequencePlayer.Update(elapsedTime);
        }

        public void StepForward(int steps)
        {
            _SequencePlayer.StepForward(steps);
        }

        public void Start(float AnimationSpeed)
        {
            _SequencePlayer.Start(AnimationSpeed);
        }

        public void Stop()
        {
            Reset();
        }

        // player next clip
        public void NextClip()
        {
            _CurrnetClipIndex = (_CurrnetClipIndex + 1) % _Sequences.Count;
            SetAnimationClip(_CurrnetClipIndex);

            //System.Diagnostics.Debug.WriteLine(_CurrnetClipIndex + _Sequences[_CurrnetClipIndex].Name);
        }

        public int FindName(string name)
        {
            int ret = -1;
            for (int i = 0; i < _Sequences.Count; i++)
                if (name.ToLower().CompareTo(_Sequences[i].Name.ToLower()) == 0)
                {
                    ret = i;
                    break;
                }
            return ret;
        }

        public CSequence this[int index]
        {
            get
            {
                return _Sequences[index];
            }
        }
    }

    public class SequencePlayer
    {
        private CSequence _Sequence;

        private bool _IsPlaying;
        private int _CurrentTick;
        private float _AnimateSpeed;

        public CSequence Sequence
        {
            get
            {
                return _Sequence;
            }
        }

        public int CurrentTick
        {
            get { return _CurrentTick; }
        }

        public bool IsPlaying
        {
            get { return _IsPlaying; }
        }

        public float FastMode
        {
            get;
            set;
        }

        public SequencePlayer(CSequence sequence)
        {
            FastMode = -1;
            Debug.Assert(sequence != null);

            _Sequence = sequence;
            _CurrentTick = _Sequence.IntervalStart;
        }

        public void Reset()
        {
            FastMode = -1;
            _IsPlaying = false;
            _CurrentTick = _Sequence.IntervalStart;
            _AnimateSpeed = 1.0f;
        }

        public void Update(TimeSpan elapsedTime)
        {
            if (_IsPlaying)
            {
                StepForward((int)(elapsedTime.TotalSeconds * 1000 * _AnimateSpeed));
            }
        }

        public void StepForward(int steps)
        {
            if (FastMode > 0)
                steps = (int)(steps * FastMode);

            _CurrentTick += steps;
            if (_CurrentTick < _Sequence.IntervalStart)
            {
                _CurrentTick = (_CurrentTick - _Sequence.IntervalStart) % (_Sequence.IntervalEnd - _Sequence.IntervalStart) +
                    _Sequence.IntervalEnd;
            }
            if (_CurrentTick >= _Sequence.IntervalEnd)
            {
                if (_Sequence.NonLooping || FastMode > 0)
                    Stop();
                else
                    _CurrentTick = (_CurrentTick - _Sequence.IntervalEnd) % (_Sequence.IntervalEnd - _Sequence.IntervalStart) +
                        _Sequence.IntervalStart;
            }
        }

        public void Start(float AnimationSpeed)
        {
            _CurrentTick = _Sequence.IntervalStart;
            _IsPlaying = true;
            this._AnimateSpeed = AnimationSpeed;
        }

        public void Stop()
        {
            Reset();
        }
    }
}
